import requests
from typing import Generator, Optional, Dict, Any, List
import json
import os
from dotenv import load_dotenv

load_dotenv()

class DeepSeekAPI:
    def __init__(self):
        self.base_url = "https://api.siliconflow.cn/v1/chat/completions"
        self.api_key = os.getenv("DEEPSEEK_API_KEY")
        self.default_headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        self.system_message = """你是一个专业的前端开发助手。请严格按照以下规则返回代码：

1. 只返回一个完整的 Vue 3 组件代码，不要包含任何解释或其他文本
2. 使用 <script setup lang="ts"> 和 Composition API
3. 使用 Tailwind CSS 实现所有样式，不使用 <style> 标签
4. 代码必须是可以直接复制到 .vue 文件中并运行的
5. 包含完整的类型定义和 props 验证
6. 遵循以下规范：
   - 使用 TypeScript 严格类型
   - 组件逻辑使用 composables
   - 添加 JSDoc 注释
   - 使用 Tailwind 现代设计（圆角、阴影、过渡动画）
   - 响应式设计（使用 md: lg: 断点）
   - 8px 间距系统
   - 交互元素有 hover/focus 状态

示例格式：
<script setup lang="ts">
// 类型定义和导入
...

// 组件逻辑
...
</script>

<template>
  <!-- 组件模板 -->
</template>"""
        
        self.default_params = {
            "model": "Pro/deepseek-ai/DeepSeek-V3",
            "max_tokens": 4096,
            "stop": ["null"],
            "temperature": 0.0,
            "top_p": 0.7,
            "top_k": 50,
            "frequency_penalty": 0.5,
            "n": 1,
            "response_format": {"type": "text"},
            "tools": [
                {
                    "type": "function",
                    "function": {
                        "description": "<string>",
                        "name": "<string>",
                        "parameters": {},
                        "strict": False
                    }
                }
            ]
        }

    def _prepare_messages(self, prompt: str) -> List[Dict[str, str]]:
        """准备消息格式"""
        return [
            {"role": "system", "content": self.system_message},
            {"role": "user", "content": prompt}
        ]

    def _prepare_payload(self, prompt: str, stream: bool = False) -> Dict[str, Any]:
        """准备请求参数"""
        payload = self.default_params.copy()
        payload["messages"] = self._prepare_messages(prompt)
        payload["stream"] = stream
        return payload

    def chat_completion(self, prompt: str) -> Dict[str, Any]:
        """同步调用 DeepSeek API"""
        try:
            if not self.api_key:
                raise Exception("未设置 DEEPSEEK_API_KEY 环境变量")
            
            payload = self._prepare_payload(prompt, stream=False)
            
            print(f"正在调用 DeepSeek API...")
            print(f"URL: {self.base_url}")
            print(f"Headers: {json.dumps(self.default_headers, indent=2)}")
            print(f"Payload: {json.dumps(payload, indent=2, ensure_ascii=False)}")
            
            response = requests.post(
                self.base_url,
                json=payload,
                headers=self.default_headers,
                timeout=120
            )
            
            if response.status_code != 200:
                print(f"API 错误响应: {response.text}")
                raise Exception(f"API 返回错误状态码: {response.status_code}")
            
            return response.json()
        
        except requests.exceptions.RequestException as e:
            print(f"请求异常: {str(e)}")
            raise Exception(f"DeepSeek API 调用失败: {str(e)}")
        except Exception as e:
            print(f"其他错误: {str(e)}")
            raise

    def chat_completion_stream(self, prompt: str) -> Generator[str, None, None]:
        """流式调用 DeepSeek API"""
        try:
            payload = self._prepare_payload(prompt, stream=True)
            response = requests.post(
                self.base_url,
                json=payload,
                headers=self.default_headers,
                stream=True
            )
            response.raise_for_status()
            
            for line in response.iter_lines():
                if line:
                    if line.strip() == b'data: [DONE]':
                        break
                    if line.startswith(b'data: '):
                        json_str = line[6:].decode('utf-8')
                        try:
                            json_data = json.loads(json_str)
                            if 'choices' in json_data and json_data['choices']:
                                content = json_data['choices'][0].get('delta', {}).get('content', '')
                                if content:
                                    yield content
                        except json.JSONDecodeError:
                            continue
        except requests.exceptions.RequestException as e:
            raise Exception(f"DeepSeek API 流式调用失败: {str(e)}")

# 使用示例
"""
# 创建 .env 文件并设置 API key
DEEPSEEK_API_KEY=your_api_key_here

# 同步调用示例
deepseek = DeepSeekAPI()
response = deepseek.chat_completion("你好，请介绍一下自己")
print(response)

# 流式调用示例
for chunk in deepseek.chat_completion_stream("你好，请介绍一下自己"):
    print(chunk, end='', flush=True)
""" 